package com.umeox.watch.moto.contact.ui;


import static com.umeox.watch.moto.dataservice.DataProvider.isVideoCallForbidden;

import android.content.BroadcastReceiver;
import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.CallLog;
import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.umeox.moto.common.clicklistener.OnNoDoubleClickListener;
import com.umeox.moto.common.constant.Features;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.NetUtils;
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity;
import com.umeox.moto.watch.themes.dialog.ActionOptionsDialog;
import com.umeox.moto.watch.themes.util.UToast;
import com.umeox.moto.watch.themes.widget.ImageView;
import com.umeox.moto.watch.themes.widget.TextView;
import com.umeox.watch.moto.agora.InternalConstants;
import com.umeox.watch.moto.contact.R;
import com.umeox.watch.moto.contact.adapter.ContactsAdapter;
import com.umeox.watch.moto.contact.model.ContactDetail;
import com.umeox.watch.moto.contact.utils.Utils;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.dataservice.proxy.PushApiClientProxy;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Created by Rambo 2021/8/30
 * Describe:
 */
public class ContactsActivity extends ThemeAppCompatActivity implements ContactsAdapter.OnItemClickListener, ActionOptionsDialog.OnClickListener {

    private static final long UNTIL_TIME = TimeUnit.MINUTES.toMillis(5);
    private HandlerThread handlerThread;
    private Handler mHandler;
    private PushApiClientProxy apiClientProxy;
    private ContactsAdapter mAdapter;
    private final int[] DESTS = {R.string.call_voice, R.string.call_voice_calls, R.string.call_video};
    private final int[] ICONS = {R.drawable.contact_voice_call,
            R.drawable.contact_voice_voip_call,
            R.drawable.contact_video_call};

    private final int[] DESTS_NO_VIDEO = {R.string.call_voice, R.string.call_voice_calls};
    private final int[] ICONS_NO_VIDEO = {R.drawable.contact_voice_call,
            R.drawable.contact_voice_voip_call};

    private final int[] DESTS_NO_VOICE = {R.string.call_voice, R.string.call_video};
    private final int[] ICONS_NO_VOICE = {R.drawable.contact_voice_call,
            R.drawable.contact_video_call};

    private final int[] DESTS_NO_VIDEO_VOICE = {R.string.call_voice};
    private final int[] ICONS_NO_VIDEO_VOICE = {R.drawable.contact_voice_call};

    private ContactDetail mSelectedContact;
    /*通知清除通话记录*/
    private static final String ACTION_CLEAR_NOTIFY_CONTACT = "com.wherecom.intent.action.CLEAR_NOTIFY_CONTACT";
    private static final String ACTION_MISS_CALL = "com.wherecom.intent.action.MISS_CALL";
    public static final String EXTRA_CONTACT_NUMBER = "extra_contact_number";
    private ArrayList<String> mNumbers = new ArrayList<>();
    private boolean mSended;
    private MissCallReceiver mReceiver;

    private TextView mNoDataTv;

    private ImageView mAddFriendIv;

    private boolean isPTT = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_contact_record_list);
        handlerThread = new HandlerThread("get-contacts");
        handlerThread.start();
        mHandler = new Handler(handlerThread.getLooper(), callback);
        Uri dataUri = getIntent().getData();
        if (dataUri != null && "contact".equals(dataUri.getScheme()) && "/PTT_CHOOSE_CONTACT".equals(dataUri.getPath())) {
            isPTT = true;
        }
        initView();
        mHandler.sendEmptyMessage(0);
        DataProvider.ContactProvider.registerContentObserver(true, mObserver);
        DataProvider.VideoCallProvider.registerContentObserver(true, mObserver);
        mReceiver = new MissCallReceiver();
        registerReceiver(mReceiver, new IntentFilter(ACTION_MISS_CALL));

    }

    private void initView() {

        RecyclerView contactListRv = findViewById(R.id.contactList);
        mNoDataTv = findViewById(R.id.tv_no_data);
        mAddFriendIv = findViewById(R.id.iv_add_friend);

        mAddFriendIv.setVisibility(DataProvider.isActivated() ? View.VISIBLE : View.GONE);

        contactListRv.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new ContactsAdapter(this);
        contactListRv.setHasFixedSize(true);
        contactListRv.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(this);
        mAddFriendIv.setOnClickListener(new OnNoDoubleClickListener() {
            @Override
            protected void onNoDoubleClick(View v) {
                Intent intent = new Intent();
                intent.setClassName("com.umeox.watch.moto.chat", "com.umeox.watch.moto.chat.ui.PairingActivity");
                startActivity(intent);
            }
        });

    }


    private void refreshDataSet() {
        mNumbers.clear();
        final ArrayList<ContactDetail> contactList = Utils.getPhoneContacts(this);
        if (contactList.isEmpty() && DataProvider.isActivated()) {
            mHandler.sendEmptyMessage(1);
            return;
        }
        for (int i = 0; i < contactList.size(); i++) {
            final ContactDetail contactDetail = contactList.get(i);
            mNumbers.add(contactDetail.getContactNumber());
            final boolean admin = contactDetail.isAdmin();
            if (admin) {
                Collections.swap(contactList, i, 0);
            }
        }


        runOnUiThread(() -> {
                    if (mAdapter != null) {

                        mAdapter.setDataList(contactList, isPTT);
                        mNoDataTv.setVisibility(contactList.isEmpty() ? View.VISIBLE : View.GONE);
                    }

                    if (!mSended) {
                        Intent intent = new Intent();
                        intent.putStringArrayListExtra(EXTRA_CONTACT_NUMBER, mNumbers);
                        intent.setAction(ACTION_CLEAR_NOTIFY_CONTACT);
                        sendBroadcast(intent);
                        mSended = true;
                    }
                }
        );

    }

    Handler.Callback callback = msg -> {
        if (msg.what == 0) {
            refreshDataSet();
            return true;
        } else if (msg.what == 1) {
            refreshDataForRemote();
            return true;
        }
        return false;
    };


    private void refreshDataForRemote() {
        if (apiClientProxy == null) {
            apiClientProxy = (PushApiClientProxy) PushApiClientProxy.fetchBinder();
        }
        try {
            apiClientProxy.requestGetContacts();
        } catch (Exception e) {
            Logger.e("获取联系人失败>>>" + e);
            e.printStackTrace();

        }
    }

    private ContentObserver mObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            mHandler.sendEmptyMessage(0);
        }
    };


    @Override
    public void onPause() {
        super.onPause();
        resetNewCallsFlag();
        mSended = false;
    }


    @Override
    public void onDestroy() {
        Intent intent = new Intent();
        intent.putStringArrayListExtra(EXTRA_CONTACT_NUMBER, null);
        intent.setAction(ACTION_CLEAR_NOTIFY_CONTACT);
        sendBroadcast(intent);
        try {
            getContentResolver().unregisterContentObserver(mObserver);
            if (mReceiver != null) {
                unregisterReceiver(mReceiver);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        handlerThread.quit();
        mHandler.removeCallbacksAndMessages(null);
        super.onDestroy();
    }

    private void resetNewCallsFlag() {
        //修改数据库字段，使改条通话记录不是最新通知 防止机器重新启动后又有未接电话通知
        // Mark all "new" missed calls as not new anymore
        final List<ContactDetail> dataList = mAdapter.getDataList();
        ArrayList<ContentProviderOperation> list = new ArrayList<>();
        for (ContactDetail contactDetail : dataList) {
            final String number = contactDetail.getContactNumber();
            if (TextUtils.isEmpty(number)) {
                continue;
            }
            ContentValues values = new ContentValues(1);
            values.put(CallLog.Calls.NEW, "0");
            final ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(CallLog.Calls.CONTENT_URI);
            builder.withValues(values)
                    .withSelection("type =? AND new=? AND number=?", new String[]{"3", "1", number});
            list.add(builder.build());

        }
        try {
            getContentResolver().applyBatch(CallLog.AUTHORITY, list);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String where = DataProvider.VideoCallProvider.NEW_CALL + "=1";
        ContentValues values = new ContentValues(1);
        values.put(DataProvider.VideoCallProvider.NEW_CALL, 0);
        getContentResolver().update(DataProvider.VideoCallProvider.getUri(), values, where, null);
    }


    @Override
    public void onItemClick(ContactDetail contactDetail) {
        if (contactDetail == null) {
            return;
        }

        mSelectedContact = contactDetail;
        if (isPTT) {
            String uri = InternalConstants.OUTGOING_PTT_CALL + "?" + InternalConstants.CALL_QUERY_PARA_FOLLOWER_ID + "=" + contactDetail.getFriendId();
            Intent intent = new Intent(InternalConstants.ACTION_PTT_CALL, Uri.parse(uri));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        } else {
            int friendType = mSelectedContact.getType();
            if (friendType == 4) {
                if (mSelectedContact == null) {
                    return;
                }
                if (NetUtils.hasSimCard()) {
                    phoneCall();
                } else {
                    showToast(getResources().getString(R.string.sim_state_unknown));
                }

                return;
            }
            String hiddenFeatures = DataProvider.getHiddenFeaturesByFriendId(mSelectedContact.getFriendId());
            Logger.e("hiddenFeatures=" + hiddenFeatures);
            ActionOptionsDialog dialog;
            if (friendType == 2) {//好友
                if (hiddenFeatures(hiddenFeatures, Features.VIDEO_CALL)) {
                    dialog = new ActionOptionsDialog(this, DESTS_NO_VIDEO, ICONS_NO_VIDEO, this);
                } else {
                    dialog = new ActionOptionsDialog(this, DESTS, ICONS, this);
                }
            } else {
                dialog = new ActionOptionsDialog(this, DESTS, ICONS, this);
            }
            dialog.setOnClickListener(this);
            dialog.show();
            isVideoCallForbidden();
            dialog.setChildViewEnabled(1, true);
        }

    }

    private boolean hiddenFeatures(String hiddenFeatures, String featuresStr) {
        if (TextUtils.isEmpty(hiddenFeatures)) {
            return false;
        }
        return hiddenFeatures.contains(featuresStr);
    }

    /**
     * 打电话
     */
    @Override
    public void onOption1Click() {
        if (mSelectedContact == null) {
            return;
        }
        phoneCall();

    }

    /**
     * .
     * 视频通话
     */
    @Override
    public void onOption2Click() {
        Logger.d("onOption2Click: " + Utils.isPhoneIdle(this));
        if (!Utils.isPhoneIdle(this)) {
            return;
        }
        if (!NetUtils.isNetworkAvailable()) {
            showToast(getResources().getString(R.string.sim_state_unknown));
            return;
        }
        int friendType = mSelectedContact.getType();
        final String friendId = mSelectedContact.getFriendId();

        if (friendType == 4) {
            showToast(getResources().getString(R.string.contact_not_video_call_str));
        } else {
//            final long lastVideoCallTimeMillis = MMKV.defaultMMKV().getLong(mSelectedContact.getFriendId(), -UNTIL_TIME);
//            final long videoCallEnableTime = lastVideoCallTimeMillis + UNTIL_TIME - SystemClock.elapsedRealtime();
//            if (videoCallEnableTime > 0) {
//
//                final int minutes = (int) Math.max(1, TimeUnit.MILLISECONDS.toMinutes(videoCallEnableTime));
//                int resId = R.string.video_call_countdown;
//                showToast(getResources().getString(resId, minutes));
//                return;
//            }

            Uri uri = Uri.parse(InternalConstants.OUTGOING_VOICE_CALL + "?" + InternalConstants.CALL_QUERY_PARA_FOLLOWER_ID + "=" + friendId);
            Intent intent = new Intent(InternalConstants.ACTION_OUTGOING_VIDEO_CALL, uri);
            startActivity(intent);
        }
    }

    private void showToast(String string) {
        runOnUiThread(() -> UToast.showCustomToast(ContactsActivity.this, string, Toast.LENGTH_LONG));

    }

    private void phoneCall() {
        if (!Utils.isPhoneIdle(mContext)) {
            Logger.i("电话功能正在使用");
            Utils.endCall(mContext);
            return;
        }
        String phoneNumber = mSelectedContact.getContactNumber();
        if (TextUtils.isEmpty(phoneNumber)) {
            return;
        }
        Settings.System.putInt(mContext.getContentResolver(), "monitor_call", 0);
        if (PhoneNumberUtils.isEmergencyNumber(phoneNumber)) {
            Intent intent = new Intent("android.intent.action.CALL_PRIVILEGED", Uri.parse("tel:" + phoneNumber));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        } else {
            if (!NetUtils.hasSimCard()) {
                UToast.showCustomToast(ContactsActivity.this, getString(R.string.no_simcard_str), Toast.LENGTH_LONG);
                return;
            }
            Intent intent = new Intent("android.intent.action.CALL_PRIVILEGED", Uri.parse("tel:" + phoneNumber));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    }

    /**
     * 语音通话
     */
    @Override
    public void onOption3Click() {
        Logger.d("onOption2Click: " + Utils.isPhoneIdle(this));
        if (!Utils.isPhoneIdle(this)) {
            return;
        }
        if (!NetUtils.isNetworkAvailable()) {
            showToast(getResources().getString(R.string.sim_state_unknown));
            return;
        }
        int friendType = mSelectedContact.getType();
        final String friendId = mSelectedContact.getFriendId();

        if (isVideoCallForbidden()) {
            showToast(getResources().getString(R.string.video_call_forbid_str));
        } else if (friendType == 4) {
            showToast(getResources().getString(R.string.contact_not_video_call_str));
        } else {
//            final long lastVideoCallTimeMillis = MMKV.defaultMMKV().getLong(mSelectedContact.getFriendId(), -UNTIL_TIME);
//            final long videoCallEnableTime = lastVideoCallTimeMillis + UNTIL_TIME - SystemClock.elapsedRealtime();
//            if (videoCallEnableTime > 0) {
//
//                final int minutes = (int) Math.max(1, TimeUnit.MILLISECONDS.toMinutes(videoCallEnableTime));
//                int resId = R.string.video_call_countdown;
//                showToast(getResources().getString(resId, minutes));
//                return;
//            }

            Uri uri = Uri.parse(InternalConstants.OUTGOING_VIDEO_CALL + "?" + InternalConstants.CALL_QUERY_PARA_FOLLOWER_ID + "=" + friendId);
            Intent intent = new Intent(InternalConstants.ACTION_OUTGOING_VIDEO_CALL, uri);
            startActivity(intent);
        }
    }

    @Override
    public void onOption4Click() {

    }


    public class MissCallReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String phoneNumber = intent.getStringExtra("phone_number");
            final List<ContactDetail> contactDetailList = mAdapter.getDataList();
            for (int i = 0; i < contactDetailList.size(); i++) {
                final ContactDetail contactDetail = contactDetailList.get(i);

                if (TextUtils.equals(phoneNumber, contactDetail.getContactNumber())) {
                    final int index = i;
                    runOnUiThread(() -> {
                        contactDetail.setMissed(true);
                        mAdapter.notifyItemChanged(index);
                    });
                }
            }

        }
    }


}